package com.uh.rds.testing.validator.types;

import com.uh.rds.testing.validator.DataValidatorBase;

import java.util.Collection;
import java.util.List;
import java.util.Map;

public class ZsetDataValidator extends DataValidatorBase {

    @Override
    public String getType() {
        return "ZSet";
    }

    @Override
    public void process() {
        if (!processJedis.isConnected()) processJedis.connect();

        processBeginLog();

        for (Map.Entry<String, List<String[]>> entry : data.entrySet()) {
            String key = entry.getKey();
            boolean succeed = true;
            String[][] values = entry.getValue().toArray(new String[0][0]);
            for (int i = 0; i < values.length; i++) {
                String[] element = values[i];
                if(processJedis.zadd(key, Double.parseDouble(element[0]), element[1]) != 1) {
                    logger.error("{} key[{}] value[{}] insert failed!", getName(), key, element[1]);
                    succeed = false;
                }
            }

            processingLog(succeed);
        }

        processEndLog();
    }

    @Override
    public long expire(int expireSeconds) {
        return super.expire(processJedis, data.keySet(), expireSeconds);
    }

    @Override
    public boolean validateExpired() {
        return super.validateExpired(validateJedis, data.keySet());
    }


    @Override
    public boolean validate() {
        if (!validateJedis.isConnected()) validateJedis.connect();

        validateBeginLog();

        Collection<String> keys = arguments.isValidateReversed() ? reversedKeys : data.keySet();
        for(String key : keys) {
            boolean keyMatched = true;
            List<String[]> values = data.get(key);

            long subSizeExpected = values.size();
            long subSizeActual = validateJedis.zcard(key);
            if (subSizeActual != subSizeExpected) {
                keyMatched = false;
                logger.error("{} key[{}] validate failed! Expected size:{} actual size:{}", getName(),  key, subSizeExpected, subSizeActual);
            }

            for (String[] subValue : values) {
                Double subScore = validateJedis.zscore(key, subValue[1]);
                if (subScore == null) {
                    keyMatched = false;
                    logger.error("{} key[{}] validate failed! Expected sub value:{} not found!", getName(), key, subValue[1]);
                }else {
                    if (!subScore.equals((double)Integer.parseInt(subValue[0])) ) {
                        keyMatched = false;
                        logger.error("{} key[{}] validate failed! sub value:{} is score{} is not expected {} ", getName(), key, subValue[1], subScore, subValue[0]);
                    }
                }
            }

            validatingLog(keyMatched);
        }

        return validateEndLog();
    }

    @Override
    public long clear() {
        return clear(processJedis, validateJedis, data.keySet());
    }
}
